package com.fgba.express.security;

import com.fgba.express.comm.GlobalConst;
import com.fgba.express.data.service.IMenuService;
import com.fgba.express.util.BeanContextUtil;
import com.fgba.express.util.CommonUtils;
import com.fgba.express.util.NullChecker;
import com.fgba.express.util.RedisUtil;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import java.util.*;

/**
 * 动态权限数据源，用于获取动态权限规则
 *
 */

public class DynamicSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        List<String> list = this.getConfigAttributes();
        List<ConfigAttribute> configAttributes = new ArrayList<>();
        //获取当前访问的路径
        String url = ((FilterInvocation) o).getRequestUrl();
        //获取访问该路径所需资源
        for (String pattern : list) {
            if (this.match(pattern, url)) {
                configAttributes.add((ConfigAttribute) () -> pattern);
            }
        }
        // 未设置操作请求权限，返回空集合（查询通常不设置）
        return configAttributes;
    }

    private boolean match(String pattern, String url) {
        if (!NullChecker.isNullOrEmpty(pattern) && !NullChecker.isNullOrEmpty(url)) {
            String[] strings = url.split("/");
            int index = url.indexOf("?");
            String newUrl;
            if (index != -1) {
                newUrl = url.substring(0, index);
            }
            if (CommonUtils.isNumeric(strings[strings.length - 1]) || "list".equals(strings[strings.length - 1]) || "list-page".equals(strings[strings.length - 1])) {
                newUrl = CommonUtils.toString(strings, ":", 0, strings.length - 1);
            } else {
                newUrl = CommonUtils.toString(strings, ":", 0, strings.length);
            }
            if (CommonUtils.isNumeric(strings[strings.length - 1]) && "id".equals(strings[strings.length - 2])) {
                newUrl = CommonUtils.toString(strings, ":", 0, strings.length - 2);
            }

            return pattern.equals(newUrl);
        }
        return false;
    }

    private List<String> getConfigAttributes() {
        List<String> configAttributes = (List<String>) BeanContextUtil.getBean(RedisUtil.class).get(GlobalConst.CONFIG_ATTRIBUTES);
        if (NullChecker.isNull(configAttributes)) {
            configAttributes = BeanContextUtil.getBean(IMenuService.class).getConfigAttributes();
            BeanContextUtil.getBean(RedisUtil.class).set(GlobalConst.CONFIG_ATTRIBUTES, configAttributes);
        }
        return configAttributes;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }

}
